package controller

import (
	"encoding/json"
	"errors"
	"log"
	"strconv"

	"gitee.com/liuyun-luo/MagicStreamMovies/Server/config"
	"gitee.com/liuyun-luo/MagicStreamMovies/Server/global"
	"gitee.com/liuyun-luo/MagicStreamMovies/Server/models"
	"gitee.com/liuyun-luo/MagicStreamMovies/Server/utils"
	"github.com/gin-gonic/gin"
	"gorm.io/gorm"
)

func RegisterUser(ctx *gin.Context) {
	var user models.User

	//获取参数
	if err := ctx.ShouldBindJSON(&user); err != nil {
		ctx.JSON(400, gin.H{
			"error": err.Error(),
		})
		return
	}

	//加密密码
	hashPwd, err := utils.HashPassword(user.Password)
	if err != nil {
		ctx.JSON(500, gin.H{
			"error": err.Error(),
		})
		return
	}

	//更新密码
	user.Password = hashPwd

	//判断有没有与当前用户的邮箱相同的
	if err := global.MySQLDb.Where("email = ?", user.Email).First(&user).Error; err != nil {
		if errors.Is(err, gorm.ErrRecordNotFound) { //如果没找到

		} else {
			ctx.JSON(500, gin.H{
				"error": err.Error(),
			})
			return
		}
	} else { //如果有相同的邮箱就是重复注册
		ctx.JSON(400, gin.H{
			"error": "该邮箱已被注册！",
		})
		return
	}

	//插入到数据库
	if err := global.MySQLDb.Create(&user).Error; err != nil {
		ctx.JSON(500, gin.H{
			"error": "插入数据库失败！err: " + err.Error(),
		})
		return
	}

	//插入成功
	ctx.JSON(201, gin.H{
		"msg": "注册成功！",
	})
}

func LoginUser(ctx *gin.Context) {
	//获取参数
	var login_input models.UserLogin

	if err := ctx.ShouldBindJSON(&login_input); err != nil {
		ctx.JSON(400, gin.H{
			"error": err.Error(),
		})
		return
	}

	//根据邮箱查询读取数据库
	var user models.User
	if err := global.MySQLDb.Where("email = ?", login_input.Email).First(&user).Error; err != nil {
		ctx.JSON(404, gin.H{
			"error": err.Error(),
		})
		return
	}

	//比较密码是否相等
	if !utils.CheckPassword(login_input.Password, user.Password) {
		ctx.JSON(400, gin.H{
			"error": "密码错误！",
		})
		return
	}

	//生成jwt令牌和对应的刷新令牌
	token, refresh_token, err := utils.GenerateJWT(strconv.FormatUint(uint64(user.ID), 10), user.Email, user.Name, user.Role)
	if err != nil {
		ctx.JSON(500, gin.H{
			"error": err.Error(),
		})
		return
	}

	key_val, err := json.Marshal(user)
	if err != nil {
		log.Printf("添加用户信息到缓存失败,user_id: %d,err: %v", user.ID, err)
	} else {
		//把用户信息添加到缓存
		key_name := config.UserKeyName + ":" + strconv.FormatUint(uint64(user.ID), 10)
		if err := global.RedisDB.Set(key_name, key_val, config.GetDefaultCacheExpirationTime()).Err(); err != nil {
			log.Printf("添加用户信息到缓存失败,user_id: %d,err: %s", user.ID, err.Error())
		}
		log.Printf("添加用户信息到缓存成功,user_id: %d", user.ID)
	}

	//填充并返回DTO对象
	ctx.JSON(200, models.UserResponse{
		UserId:          user.ID,
		Name:            user.Name,
		Email:           user.Email,
		Role:            user.Role,
		Token:           token,
		RefreshToken:    refresh_token,
		FavouriteGenres: user.FavouriteGenres,
	})
}
